﻿Imports System.IO
Imports System.ComponentModel
Imports System.Text
Imports System.Security.Permissions
Imports System.Net
Imports System.Threading



''' <summary>
''' 扩展 WebClient 类
''' </summary>
''' <remarks></remarks>
Public Class WebClient
    Inherits System.Net.WebClient

#Region "variable"

#End Region

#Region "property"

    Private m_Url As String = String.Empty
    ''' <summary>
    ''' 访问的网络地址
    ''' </summary>
    Public ReadOnly Property Url() As String
        Get
            Return m_Url
        End Get
    End Property


    Private m_HtmlEncode As Encoding = Encoding.Default
    ''' <summary>
    ''' 编码方式
    ''' </summary>
    Public Property HtmlEncode() As Encoding
        Get
            Return m_HtmlEncode
        End Get
        Set(ByVal value As Encoding)
            m_HtmlEncode = value
        End Set
    End Property


    Private m_CooContainer As CookieContainer
    Public Property CooContainer() As CookieContainer
        Get
            Return m_CooContainer
        End Get
        Set(ByVal value As CookieContainer)
            m_CooContainer = value
        End Set
    End Property


#End Region

#Region "constructed function"

    Public Sub New()
        MyBase.New()

        Me.m_CooContainer = Nothing
    End Sub

    Public Sub New(ByVal cc As CookieContainer)
        MyBase.New()

        Me.m_CooContainer = cc
    End Sub

#End Region

#Region "delegate"
    Public Delegate Sub GetHtmlCodeCompletedEventHandler(ByVal sender As Object, ByVal e As GetHtmlCodeCompletedEventArgs)
#End Region

#Region "event"
    Public Event GetHtmlCodeCompleted As GetHtmlCodeCompletedEventHandler
    Protected Overridable Sub OnGetHtmlCodeCompleted(ByVal e As GetHtmlCodeCompletedEventArgs)
        If e IsNot Nothing Then
            RaiseEvent GetHtmlCodeCompleted(Me, e)
        End If
    End Sub

#End Region

#Region "prvate method"

    Private Sub WebClient_DownloadDataCompleted(ByVal sender As Object, ByVal e As DownloadDataCompletedEventArgs)
        Dim _Byte() As Byte = Nothing
        Dim _Encoding As System.Text.Encoding = Me.m_HtmlEncode
        Dim _HtmlCode As String = String.Empty

        Try
            If e.Error Is Nothing AndAlso e.Result IsNot Nothing Then
                _Byte = e.Result
                _HtmlCode = _Encoding.GetString(_Byte)
            End If

            Me.OnGetHtmlCodeCompleted(New GetHtmlCodeCompletedEventArgs(e.Error, e.Cancelled, _
                                                                        Me.Url, _
                                                                        _HtmlCode, _
                                                                        e.UserState))
        Catch ex As Exception
            Me.OnGetHtmlCodeCompleted(New GetHtmlCodeCompletedEventArgs(ex, True, e.UserState))
            'Finally
            '    With DirectCast(sender, System.Net.WebClient)
            '        .CancelAsync()
            '        .Dispose()
            '    End With
        End Try
    End Sub

    Private Sub addHeaders()
        Me.Headers.Add("USER-AGENT", "Mozilla/4.0 (compatible; MSIE 6.0; MSIE 7.0; MSIE 8.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)")
        Me.Headers.Add("ACCEPT", String.Concat("image/*, ", _
                       "application/x-shockwave-flash, application/x-silverlight, application/vnd.ms-excel, ", _
                       "application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, ", _
                       "application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight-2-b1, */*"))
    End Sub

#End Region


#Region "public method"

    Public Overloads Function OpenRead(ByVal address As String) As Stream
        Me.addHeaders()
        Return MyBase.OpenRead(address)
    End Function

    <HostProtectionAttribute(SecurityAction.LinkDemand, ExternalThreading:=True)> _
    Public Overloads Sub DownloadFileAsync(ByVal address As Uri, ByVal fileName As String)
        Me.addHeaders()
        MyBase.DownloadFileAsync(address, fileName)
    End Sub

    ''' <summary>
    ''' 自动编码方式，获取网页源码
    ''' </summary>
    ''' <param name="url"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetHtmlCode(ByVal url As String) As String
        Dim _HtmlCode As String = String.Empty
        Dim _Encoding As System.Text.Encoding = System.Text.Encoding.Default

        Me.m_Url = url
        Try
            Using _WebClient As New System.Net.WebClient()
                Dim _Byte() As Byte = _WebClient.DownloadData(url)
                _HtmlCode = _Encoding.GetString(_Byte)
            End Using
        Catch ex As Exception
            Throw ex
        Finally

        End Try

        Return _HtmlCode
    End Function


    ''' <summary>
    ''' 自动编码方式，异步获取网页源码
    ''' </summary>
    ''' <param name="url"></param>
    ''' <remarks></remarks>
    <HostProtectionAttribute(SecurityAction.LinkDemand, ExternalThreading:=True)> _
    Public Sub GetHtmlCodeAsync(ByVal url As String)
        If String.IsNullOrEmpty(url) = False Then
            Me.GetHtmlCodeAsync(New Uri(url))
        Else
            Me.OnGetHtmlCodeCompleted(New GetHtmlCodeCompletedEventArgs(New Exception("网络地址为空，无法获取网页源码"), False, Me))
        End If
    End Sub

    ''' <summary>
    ''' 自动编码方式，异步获取网页源码
    ''' </summary>
    ''' <param name="uri"></param>
    ''' <remarks></remarks>
    <HostProtectionAttribute(SecurityAction.LinkDemand, ExternalThreading:=True)> _
    Public Sub GetHtmlCodeAsync(ByVal uri As Uri)
        Me.m_Url = uri.AbsoluteUri

        Try
            Dim _WebClient As New System.Net.WebClient()
            With _WebClient
                .Headers.Add("USER-AGENT", "Mozilla/4.0 (compatible; MSIE 6.0; MSIE 7.0; MSIE 8.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)")
                .Headers.Add("ACCEPT", String.Concat("image/*, ", _
                             "application/x-shockwave-flash, application/x-silverlight, application/vnd.ms-excel, ", _
                             "application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, ", _
                             "application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight-2-b1, */*"))
                AddHandler .DownloadDataCompleted, AddressOf Me.WebClient_DownloadDataCompleted
                AddHandler .DownloadProgressChanged, Function(sender As Object, e As ProgressChangedEventArgs)
                                                         Me.OnDownloadProgressChanged(e)
                                                         Return Nothing
                                                     End Function
                .DownloadDataAsync(uri, _WebClient)
            End With

        Catch ex As Exception
            Me.OnGetHtmlCodeCompleted(New GetHtmlCodeCompletedEventArgs(ex, True, Me))
        End Try
    End Sub

#End Region


End Class
